package chapter3;

import java.util.concurrent.atomic.AtomicLong;

/**
 * @author ycj
 * @version 1.0
 * @description: TODO
 * @date 2022/5/18
 */


//基于原子变量的指标器
public class Source3_20 {
    public static void main(String[] args) {
        Thread[] threads=new Thread[15];
        Indicator indicator = Indicator.getIndicator();
        for(int i=0;i<5;i++){
            threads[i]=new Thread(()->{
               indicator.addRequestCount();
                System.out.println("RequestCount="+indicator.getRequestCount());
            });
        }
        for(int i=5;i<10;i++){
            threads[i]=new Thread(()->{
                indicator.addSuccessCount();
                System.out.println("SuccessCount="+indicator.getSuccessCount());
            });
        }

        for(int i=10;i<15;i++){
            threads[i]=new Thread(()->{
                indicator.addFailureCount();
                System.out.println("FailureCount="+indicator.getFailureCount());
            });
        }

        for(int i=0;i<15;i++){
            threads[i].start();
        }

    }
}

class Indicator{
    private final AtomicLong successCount=new AtomicLong(0);
    private final AtomicLong requestCount=new AtomicLong(0);
    private final AtomicLong failureCount=new AtomicLong(0);
    private  static volatile Indicator indicator;

    private Indicator() {
    }

    public static Indicator getIndicator(){
        if(null==indicator){
            synchronized (Indicator.class){
                if(null==indicator){
                    indicator=new Indicator();
                }
            }
        }
        return indicator;
    }

    public void reset(){
        successCount.set(0);
        requestCount.set(0);
        failureCount.set(0);
    }

    public void addSuccessCount(){
        //原子类的自增操作具有原子性 不需要加锁
        successCount.incrementAndGet();
    }

    public void addRequestCount(){
        requestCount.incrementAndGet();
    }

    public void addFailureCount(){
        failureCount.incrementAndGet();
    }

    public long getSuccessCount() {
        return successCount.get();
    }

    public Long getRequestCount() {
        return requestCount.get();
    }

    public long getFailureCount() {
        return failureCount.get();
    }
}
